package services

import (
	"fmt"
	"math/rand"
	"mypassword/models"
	"mypassword/utils"
	"strconv"
	"time"

	"encoding/base64"

	"github.com/beego/beego/v2/client/orm"
)

type AccountService struct {
	rsaUtil *utils.RSAUtil
}

func NewAccountService() *AccountService {
	rsaUtil := utils.NewRSAUtil()
	// 初始化时加载密钥对
	err := rsaUtil.LoadKeyPair()
	if err != nil {
		println("Warning: Failed to load key pair:", err.Error())
	}
	return &AccountService{
		rsaUtil: rsaUtil,
	}
}

func (s *AccountService) GetAll() ([]*models.Account, error) {
	var accounts []*models.Account
	o := orm.NewOrm()
	_, err := o.QueryTable("account").All(&accounts)
	return accounts, err
}

func (s *AccountService) Create(account *models.Account) error {
	// 先加载密钥对
	if err := s.rsaUtil.LoadKeyPair(); err != nil {
		return fmt.Errorf("加载密钥对失败: %v", err)
	}

	// 加密密码
	encryptedBytes, err := s.rsaUtil.Encrypt([]byte(account.Password))
	if err != nil {
		return fmt.Errorf("密码加密失败: %v", err)
	}

	// 将加密后的字节数组转换为base64字符串
	account.Password = base64.StdEncoding.EncodeToString(encryptedBytes)

	o := orm.NewOrm()
	_, err = o.Insert(account)
	if err != nil {
		return fmt.Errorf("保存数据失败: %v", err)
	}

	return nil
}

func (s *AccountService) Update(account *models.Account) error {
	o := orm.NewOrm()

	// 获取原始账号信息
	oldAccount := models.Account{Id: account.Id}
	if err := o.Read(&oldAccount); err != nil {
		return err
	}

	// 如果密码被修改，需要重新加密
	if account.Password != oldAccount.Password && account.Password != "" {
		// 先加载密钥对
		if err := s.rsaUtil.LoadKeyPair(); err != nil {
			return fmt.Errorf("加载密钥对失败: %v", err)
		}

		encryptedBytes, err := s.rsaUtil.Encrypt([]byte(account.Password))
		if err != nil {
			return fmt.Errorf("密码加密失败: %v", err)
		}
		account.Password = base64.StdEncoding.EncodeToString(encryptedBytes)
	} else {
		// 如果密码没有修改，使用原密码
		account.Password = oldAccount.Password
	}

	_, err := o.Update(account)
	return err
}

func (s *AccountService) DecryptPassword(id int64, isSecondPassword bool) (string, error) {
	o := orm.NewOrm()
	account := models.Account{Id: id}
	if err := o.Read(&account); err != nil {
		return "", err
	}

	// 记录解密日志
	decryptLog := &models.DecryptLog{
		AccountId:   id,
		DecryptTime: time.Now(),
	}
	_, err := o.Insert(decryptLog)
	if err != nil {
		return "", err
	}

	// 如果是使用第二密码登录，返回随机密码
	if isSecondPassword {
		return strconv.Itoa(rand.Intn(1000000)), nil
	}

	// 先加载密钥对
	if err := s.rsaUtil.LoadKeyPair(); err != nil {
		return "", fmt.Errorf("加载密钥对失败: %v", err)
	}

	// 从base64字符串解码为字节数组
	encryptedBytes, err := base64.StdEncoding.DecodeString(account.Password)
	if err != nil {
		return "", fmt.Errorf("密码解码失败: %v", err)
	}

	// 解密密码
	decryptedBytes, err := s.rsaUtil.Decrypt(encryptedBytes)
	if err != nil {
		return "", fmt.Errorf("密码解密失败: %v", err)
	}

	return string(decryptedBytes), nil
}

func (s *AccountService) Delete(id int64) error {
	o := orm.NewOrm()

	// 先检查账号是否存在
	account := models.Account{Id: id}
	if err := o.Read(&account); err != nil {
		if err == orm.ErrNoRows {
			return fmt.Errorf("账号不存在")
		}
		return fmt.Errorf("查询账号失败: %v", err)
	}

	// 删除相关的解密日志
	_, err := o.QueryTable("decrypt_log").Filter("account_id", id).Delete()
	if err != nil {
		return fmt.Errorf("删除解密日志失败: %v", err)
	}

	// 删除账号
	_, err = o.Delete(&account)
	if err != nil {
		return fmt.Errorf("删除账号失败: %v", err)
	}

	return nil
}
